home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 22
/
Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso
/
Aminet
/
util
/
cli
/
MakePath.lha
/
MakePath
/
src
/
MakePath.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-27
|
6KB
|
291 lines
/********************************************************************
*
* File: MakePath.c
* Description: Main code module for MakePath
* Author: Ole Martin Bjørndalen (olemb@stud.cs.uit.no)
* Version: 1.1a
* Status: Public domain
* Last changed: 27 Sep 1997
*
********************************************************************/
#define __USE_SYSBASE
#include <proto/dos.h>
#include <proto/exec.h>
#include <exec/memory.h>
#include <string.h>
/* Uncomment the next line to activate debugging */
//#define DEBUG 1
#include "debug.h"
UBYTE fver[] = "$VER: MakePath 1.1a " __AMIGADATE__ " Ole Martin Bjørndalen";
/****** CliTools/MakePath *******************************************
*
* NAME
* MakePath -- Creates or completes path.
*
* TEMPLATE
* PATH/M/A
*
* FUNCTION
* MakePath attempts to create or complete the path you
* specify. Directories that do not exist will be created.
* If MakePath returns without errors, the full path is
* guaranteed to be there.
*
* MakePath does not create icons for the new drawers.
*
* ARGUMENTS
* PATH - One or more paths to create
*
* RESULT
* Returns FAIL if something went wrong, else OK.
*
* EXAMPLES
* MakePath a/short/path
* MakePath a/path another/path
* MakePath this//is//perfectly//legal
*
* NOTES
* Unlike MakeDir, MakePath will not fail if a directory
* already exists. You may want to know this when writing
* scripts.
*
* BUGS
* None known
*
* AUTHOR
* Ole Martin Bjørndalen (olemb@stud.cs.uit.no)
*
* SEE ALSO
* C:MakeDir
*
*****************************************************************************
*
*/
BOOL MakePath(struct ExecBase *SysBase,
struct DosLibrary *DOSBase,
STRPTR path);
/*
Define an argument structure for ReadArgs().
If find this is more readable than using a
LONG array, even for one argument
*/
struct Arguments {
STRPTR *path;
};
#define TEMPLATE "PATH/M/A"
/*
There is no startup code, so we'll have to do
all the setup ourselves. Most of the work is done
by dos.library, though.
*/
int startup(void)
{
LONG result = RETURN_OK;
struct ExecBase *SysBase;
struct Process *proc;
SysBase = (*((struct ExecBase **) 4));
proc = (struct Process *)FindTask(NULL);
/*
Make sure we don't crash if started from WB
*/
if(proc->pr_CLI)
{
struct DosLibrary *DOSBase;
if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36L))
{
struct RDArgs *rdargs;
struct Arguments args = { NULL };
if(rdargs = ReadArgs(TEMPLATE, (LONG *)&args, NULL))
{
int i;
for(i = 0; args.path[i]; i++)
{
if(!MakePath(SysBase, DOSBase, args.path[i]))
{
/* Failed! Let's get outta here! */
result = RETURN_FAIL;
break;
}
}
}
else
{
PrintFault(IoErr(), NULL);
result = RETURN_FAIL;
}
CloseLibrary((struct Library *)DOSBase);
}
else
{
proc->pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
}
}
else
{
/*
Started from WB. Reply startup
message and exit gracefully
*/
struct Message *msg;
WaitPort(&proc->pr_MsgPort);
if(msg = GetMsg(&proc->pr_MsgPort))
{
Forbid();
ReplyMsg(msg);
}
}
return result;
}
/*
Create the actual path. If this fails, an
error code is printed and FALSE is returned.
I use SetIoErr() because it allows me to
use PrintFault() for my own error conditions.
Thus, MakePath is fully localized.
*/
BOOL MakePath(struct ExecBase *SysBase,
struct DosLibrary *DOSBase,
STRPTR path)
{
BOOL success = FALSE;
UBYTE *buffer;
D(bug("MakePath(%s)\n", path));
/* Allocate a temporary buffer to hold the path */
if(buffer = AllocVec(strlen(path) + 1, MEMF_ANY))
{
LONG p;
// D(bug("Buffer allocated\n"));
/*
Iterate through the buffer and stop
between path components
*/
for(p = 0; ;p++)
{
if(path[p] == '/' || path[p] == '\0')
{
BPTR lock;
/*
Temporary NULL termination
*/
buffer[p] = '\0';
D(bug("Lock(%s)\n", buffer));
/*
Expect the worst. This will be
set back to TRUE if all went well
*/
success = FALSE;
/* Does the directory exist? */
if(lock = Lock(buffer, ACCESS_READ))
{
__aligned struct FileInfoBlock fib;
D(bug("Examine(%s)\n", buffer));
/* Yes, but is it really a directory? */
if(Examine(lock, &fib))
{
if(fib.fib_DirEntryType > 0)
{
success = TRUE;
}
else
{
/* fail */
SetIoErr(ERROR_OBJECT_WRONG_TYPE);
}
}
/* else fail */
}
else
{
/*
If I didn't test this, the
"please insert volume X"
requester would open twice.
Also, if a serious error has
occured, calling CreateDir()
is rather pointless.
*/
if(IoErr() == ERROR_OBJECT_NOT_FOUND)
{
D(bug("CreateDir(%s)\n", buffer));
if(lock = CreateDir(buffer))
{
success = TRUE;
}
else
{
/* fail */
D(bug("CreateDir() failed!\n"));
}
}
/* else fail */
} /* Lock() */
if(lock)
UnLock(lock);
if(!success)
{
/*
An error occured.
Inform user and bail out
*/
PrintFault(IoErr(), buffer);
break;
}
if(path[p] == '\0')
{
/* Reached the end of the string */
break;
}
} /* if('/' || '\0') */
/* Copy character to work buffer */
buffer[p] = path[p];
} /* for() */
}
else
{
PrintFault(ERROR_NO_FREE_STORE, NULL);
}
D(bug("%s\n", success ? "SUCCESS" : "FAILURE"));
return success;
}